home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / FTPSUBR.C < prev    next >
Text File  |  1993-08-09  |  5KB  |  233 lines

  1. #include <stdio.h>
  2. #include <io.h>
  3. #include "global.h"
  4. #include "mbuf.h"
  5. #include "ftp.h"
  6. #include "files.h"
  7. #include "server.h"
  8.  
  9. /* Send a file (opened by caller) on a network socket.
  10.  * Normal return: count of bytes sent
  11.  * Error return: -1
  12.  */
  13. long
  14. sendfile(FILE *fp,int s,int mode,int hash)
  15. {
  16.     struct mbuf *bp;
  17.     static char bsent[] = "Bytes sent: %ld\n";
  18.     long total = 0, hmark = 0;
  19.     int fileclose = (hash & 0x80);
  20.  
  21.     hash &= 0x7f;
  22.  
  23.     switch(mode){
  24.     default:
  25.     case IMAGE_TYPE:
  26.     case LOGICAL_TYPE:
  27.         sockmode(s,SOCK_BINARY);
  28.         for(;;){
  29.             bp = alloc_mbuf(BLKSIZE);
  30.             if((bp->cnt = fread(bp->data,1,BLKSIZE,fp)) == 0){
  31.                 free_p(bp);
  32.                 break;
  33.             }
  34.             total += bp->cnt;
  35.             if(send_mbuf(s,bp,0,NULLCHAR,0) == -1) {
  36.                 total = -1L;
  37.                 break;
  38.             }
  39.             while(hash == V_HASH && total >= hmark+1000){
  40.                 tputs("#");
  41.                 hmark += 1000;
  42.             }
  43.             while(hash == V_BYTE && total >= hmark+1000){
  44.                 tprintf(bsent,total);
  45.                 hmark += 1000;
  46.             }
  47.         }
  48.         break;
  49.     case ASCII_TYPE: {
  50.         int c, oldf = setflush(s,-1);
  51.         char line[LINELEN];
  52.  
  53.         /* Let the newline mapping code in usput.() do the work */
  54.         sockmode(s,SOCK_ASCII);
  55.  
  56.         while(fgets(line,LINELEN,fp) != NULL) {
  57.             if((c = usputs(s,line)) == EOF) {
  58.                 total = -1L;
  59.                 break;
  60.             }
  61.             total += c + 1;
  62.  
  63.             while(hash == V_HASH && total >= hmark + 1000) {
  64.                 tputs("#");
  65.                 hmark += 1000;
  66.             }
  67.             while(hash == V_BYTE && total >= hmark + 1000) {
  68.                 tprintf(bsent,total);
  69.                 hmark += 1000;
  70.             }
  71.         }
  72.         usflush(s);
  73.         setflush(s,oldf);
  74.         break;
  75.       }
  76.     }
  77.     if(hash) {
  78.         tputs("\n");
  79.     }
  80.     if(fileclose) {
  81.         Fclose(fp);
  82.     }
  83.     return total;
  84. }
  85.  
  86. /* Receive a file (opened by caller) from a network socket.
  87.  * Normal return: count of bytes received
  88.  * Error return: -1
  89.  */
  90. long
  91. recvfile(FILE *fp,int s,int mode,int hash)
  92. {
  93.     struct mbuf *bp;
  94.     static char brecv[] = "Bytes recv: %ld\n";
  95.     int c, cnt;
  96.     long total = 0, hmark = 0;
  97.  
  98.     switch(mode){
  99.     default:
  100.     case IMAGE_TYPE:
  101.     case LOGICAL_TYPE:
  102.         sockmode(s,SOCK_BINARY);
  103.  
  104.         while((cnt = recv_mbuf(s,&bp,0,NULLCHAR,0)) != 0) {
  105.             if(cnt == -1) {
  106.                 return -1;
  107.             }
  108.             total += cnt;
  109.  
  110.             while(hash == V_HASH && total >= hmark+1000){
  111.                 tputs("#");
  112.                 hmark += 1000;
  113.             }
  114.             while(hash == V_BYTE && total >= hmark+1000){
  115.                 tprintf(brecv,total);
  116.                 hmark += 1000;
  117.             }
  118.             if(fp != NULLFILE) {
  119.                 struct mbuf *tbp = bp;
  120.                 while(bp != NULLBUF) {
  121.                     if(fwrite(bp->data,1,bp->cnt,fp) != bp->cnt) {
  122.                         free_p(bp);
  123.                         return -1;
  124.                     }
  125.                     bp = bp->next;
  126.                 }
  127.                 free_p(tbp);
  128.             } else {
  129.                 send_mbuf(Curproc->output,bp,0,NULLCHAR,0);
  130.             }
  131.         }
  132.         break;
  133.     case ASCII_TYPE:
  134.         sockmode(s,SOCK_ASCII);
  135.  
  136.         while((c = recvchar(s)) != EOF) {
  137.             if(c == '\n') {
  138.                 total++;
  139.             }
  140.             if(fp != NULLFILE){
  141.                 if(fputc(c,fp) == EOF) {
  142.                     total = -1;
  143.                     break;
  144.                 }
  145.             } else {
  146.                 usputc(Curproc->output,c);
  147.             }
  148.             total++;
  149.  
  150.             while(hash == V_HASH && total >= hmark+1000){
  151.                 tputs("#");
  152.                 hmark += 1000;
  153.             }
  154.             while(hash == V_BYTE && total >= hmark+1000){
  155.                 tprintf(brecv,total);
  156.                 hmark += 1000;
  157.             }
  158.         }
  159.         /* Detect an abnormal close */
  160.         if(socklen(s,0) == -1)
  161.             total = -1L;
  162.         break;
  163.     }
  164.     if(hash) {
  165.         tputs("\n");
  166.     }
  167.     return total;
  168. }
  169.  
  170. /* Determine if a file appears to be binary (i.e., non-text).
  171.  * Return 1 if binary, 0 if ascii text after rewinding the file pointer.
  172.  *
  173.  * Used by FTP to warn users when transferring a binary file in text mode.
  174.  */
  175. int
  176. isbinary(FILE *fp)
  177. {
  178.     int c, i, rval = 0;
  179.  
  180.     for(i = 0; i < 512; i++) {
  181.         if((c = fgetc(fp)) == EOF) {
  182.             break;
  183.         }
  184.         if(c & 0x80) {
  185.             /* High bit is set, probably not text */
  186.             rval = 1;
  187.             break;
  188.         }
  189.     }
  190.     /* Assume it was at beginning */
  191.     rewind(fp);
  192.     return rval;
  193. }
  194.  
  195. /* Return 1 if the file operation is allowed, 0 otherwise */
  196. int
  197. permcheck(char *path,int perms,int op,char *file)
  198. {
  199.     if(file == NULLCHAR || path == NULLCHAR) {
  200.         return 0;    /* Probably hasn't logged in yet */
  201.     }
  202.     if(chkbaddoschars(file)) {
  203.         return 0;
  204.     }
  205.     /* The target file must be under the user's allowed search path */
  206.     if(strncmp(file,path,strlen(path)) != 0) {
  207.         return 0;
  208.     }
  209.     switch(op){
  210.     case RETR_CMD:
  211.         /* User must have permission to read files */
  212.         return (perms & FTP_READ);
  213.     case DELE_CMD:
  214.     case RMD_CMD:
  215.         /* User must have permission to (over)write files */
  216.         return (perms & FTP_WRITE);
  217.     case STOR_CMD:
  218.     case MKD_CMD:
  219.         /* User must have permission to (over)write files, or permission
  220.          * to create them if the file doesn't already exist
  221.          */
  222.         if(perms & FTP_WRITE) {
  223.             return 1;
  224.         }
  225.         if(access(file,2) == -1 && (perms & FTP_CREATE)) {
  226.             return 1;
  227.         }
  228.         return 0;
  229.     }
  230.     return 0;    /* "can't happen" -- keep lint happy */
  231. }
  232.  
  233.